<?php
// 这是系统自动生成的公共文件

/*
 *生成随机字符串
 */
function getRandChar($length): ?string
{
    $str = null;
    $strPol = 'ASDFGHJKLMNBVCXZQWERTYUIOP0123456789asdfghjklmnbvcxzqwertyuiop';
    $max = strlen($strPol) - 1;

    for ($i = 0; $i < $length; $i++) {
        $str .= $strPol[rand(0, $max)];
    }

    return $str;
}

/**
* 以迭代的方式将一个线性的菜单列表转换成树状结构
* @param array $list 线性菜单列表
* @param string $primary_key 主键字段,默认为'id'
* @param string $pid 父节点ID字段,默认为'parent_id'
* @param string $child 子节点数组字段,默认为'_child'
* @param int $root 根节点ID,默认为0
* @return array $tree 树状结构的菜单
*/
function list_to_tree($list, $primary_key = 'id', $pid = 'parent_id', $child = '_child', $root = 0): array
{
    // 结果数组
    $tree = [];

    // 输入为数组才执行转换
    if (is_array($list)) {

        // 引用关系数组
        $refer = [];

        // 建立引用关系
        foreach ($list as $key => $data) {
            $refer[$data[$primary_key]] =& $list[$key];
        }

        // 遍历列表构建树
        foreach ($list as $key => $data) {

            // 获取父节点ID
            $parentId = $data[$pid];

            $level = 1;

            if ($root === $parentId) {
                // 根节点级别为 1
                $list[$key]['level'] = $level;
                $tree[] =& $list[$key];

            } else if (isset($refer[$parentId])) {
                // 子节点级别 = 父节点级别+1
                $level = ($refer[$parentId]['level'] ?? 0) + 1;

                $list[$key]['level'] = $level;

                $parent =& $refer[$parentId];
                $parent[$child][] =& $list[$key];
            }
        }
    }

    // 返回构建的树
    return $tree;
}

/**
 * 递归方式将一个线性的菜单列表转换成树状结构
 * @param array $list 线性菜单列表
 * @param int $parentId 父节点ID,默认为0
 * @param int $level 当前层级,默认为1
 * @param string $primaryKey 主键字段,默认为'id'
 * @param string $pid 父节点ID字段,默认为'parent_id'
 * @param string $child 子节点数组字段,默认为'_child'
 * @return array $tree 树状结构的菜单
 */
function list_to_tree_recursion($list, $parentId = 0, $level = 1, $primaryKey = 'id', $pid = 'parent_id', $child = '_child'): array
{
    $tree = [];

    foreach ($list as $item) {
        if ($item[$pid] == $parentId) {
            $item['level'] = $level;
            $children = list_to_tree_recursion($list, $item[$primaryKey], $level + 1, $primaryKey, $pid, $child);

            if ($children) {
                $item[$child] = $children;
            }

            $tree[] = $item;
        }
    }

    return $tree;
}